package cn.li.controller;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.StringWriter;

import javax.annotation.Resource;

import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;

import com.thoughtworks.xstream.XStream;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/applicationContext.xml" })
public class DemoControllerTest {
 
	@Resource
	private ApplicationContext applicationContext;

	private MockHttpServletRequest request;

	private MockHttpServletResponse response;

	private AnnotationMethodHandlerAdapter handlerAdapter;

	@Resource
	private DemoController controller;
	
	@Before
	public void before() {
		System.out.println("before*********************************");
		init();
		handlerAdapter = applicationContext
				.getBean(AnnotationMethodHandlerAdapter.class);
		System.out.println("handlerAdapter------------------------");
	}
	/**
	@Test
	public void testList() throws Exception{
        //test json
		jsonGetInit();
		int pageNumber = 1;
		int pageSize = 20;
		System.out.println("testList*************");
		request.setRequestURI("/mvc/"+pageNumber+"/"+pageSize);
		System.out.println("testList*************");
		Person p1 = new Person("令狐冲",1);
		request.setContent(toJson(p1).getBytes());
		ModelAndView mav = handlerAdapter.handle(request, response, controller);
		System.out.println("mav........"+mav);
		assertNotNull(mav);
	    assertEquals(mav.getViewName(),"/personList");
	    Person p_ = (Person) mav.getModelMap().get("person");
	    
	    assertEquals(p1.getName(),p_.getName());
	    assertEquals(p1.getGender(),p_.getGender());
	    
	    //test xml 
	    xmlGetInit();
	    request.setRequestURI("/mvc/"+pageNumber+"/"+pageSize);
	    request.setContent(toXml(p1).getBytes());
	    mav = handlerAdapter.handle(request, response, controller);
		assertNotNull(mav);
	    assertEquals(mav.getViewName(),"/personList");
	    
	    p_ = (Person) mav.getModelMap().get("person");
	    
	    assertEquals(p1.getName(),p_.getName());
	    assertEquals(p1.getGender(),p_.getGender());
	    
	}
	*/
	@Test
	public void testCreate()throws Exception{
		jsonPostInit();
		request.setRequestURI("/mvc/person");
		Person p1 = new Person("令狐冲",1);
		System.out.println("错误开始？？？");
		request.setContent(toJson(p1).getBytes());
		System.out.println("错误开始？？？");
		System.out.println("controller--- "+controller);
		System.out.println("-- "+toJson(p1).getBytes());
		System.out.println("handlerAdapter---- "+handlerAdapter);
		System.out.println("request---- "+request);
		System.out.println("response---- "+response);
		ModelAndView mav = handlerAdapter.handle(request, response, controller);
		//assertNotNull(mav);
		//assertEquals(mav.getViewName(),"msg");
	   
		
		xmlPostInit();
	    request.setRequestURI("/mvc/person");
	    
	    request.setContent(toXml(p1).getBytes());
	    ModelAndView mav1 = handlerAdapter.handle(request, response, controller);
		assertNotNull(mav1);
		assertNotNull(mav1);
		assertEquals(mav1.getViewName(),"msg");
	}
	
	/**
	@Test
	public void testUpdate()throws Exception{
		jsonPutInit();
		request.setRequestURI("/mvc/person");
		Person p1 = new Person("令狐冲",1);
		request.setContent(toJson(p1).getBytes());
		ModelAndView mav = handlerAdapter.handle(request, response, controller);
		assertNotNull(mav);
		assertEquals(mav.getViewName(),"msg");
	   
		
		xmlPutInit();
	    request.setRequestURI("/mvc/person");
	    request.setContent(toXml(p1).getBytes());
	    mav = handlerAdapter.handle(request, response, controller);
		assertNotNull(mav);
		assertNotNull(mav);
		assertEquals(mav.getViewName(),"msg");
	}
	*/
	protected void jsonPostInit() {
		addJsonHeader();
		request.setMethod(RequestMethod.POST.toString());
	}

	protected void jsonGetInit() {
		addJsonHeader();
		request.setMethod(RequestMethod.GET.toString());
	}

	protected void jsonPutInit() {
		addJsonHeader();
		request.setMethod(RequestMethod.PUT.toString());
	}

	protected String toJson(Object o) throws Exception {
		System.out.println("toJson...............");
		StringWriter sw = new StringWriter();
		ObjectMapper mapper = new ObjectMapper();
		System.out.println("toJson......start.........");
		mapper.writeValue(sw, o);
		System.out.println("toJson.......end......");
		System.out.println("sw--- "+sw.toString());
		return sw.toString();
	}
	
	protected String toXml(Object o)throws Exception{
		XStream xstream = new XStream();
		xstream.autodetectAnnotations(true);
		return xstream.toXML(o);
	}

	private void addJsonHeader() {
		init();
		request.addHeader("Accept", "application/json, text/javascript, */*");
		request.addHeader("Content-Type", "application/json; charset=UTF-8");
	}


	private void addXmlHeader() {
		init();
		request.addHeader("Accept", "application/xml, text/xml, */*");
		request.addHeader("Content-Type", "application/xml; charset=UTF-8");
	}

	private void init() {
		request = new MockHttpServletRequest();
		request.setCharacterEncoding("UTF-8");
		response = new MockHttpServletResponse();
	}
	
	protected void xmlGetInit() {
		addXmlHeader();
		request.setMethod(RequestMethod.GET.toString());
	}

	protected void xmlPostInit() {
		addXmlHeader();
		request.setMethod(RequestMethod.POST.toString());
	}

	protected void xmlPutInit() {
		addXmlHeader();
		request.setMethod(RequestMethod.PUT.toString());
	}
}
